import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class Fields {
    // 这个类实现的是对于 Student 类中成员变量的获取并调用

    public static void main(String[] args) throws Exception{
        // 首先获取 class 对象
        Class stuClass = Class.forName("Student");
        // 定义出一个 Field 类型的数组，在这里接受从 student 中返回的值
        Field[] fieldArray = null;

        // 获取所有的公共类型字段
        System.out.println("********获取所有的公共字段********");
        fieldArray = stuClass.getFields();
        for (Field f : fieldArray) {
            System.out.println(f);
        }


        System.out.println("********获取所有的字段(包括私有、受保护、默认)********");
        fieldArray = stuClass.getDeclaredFields();
        for (Field f : fieldArray) {
            System.out.println(f);
        }

        // 获取公共字段并且尝试进行调用
        System.out.println("********获取公共字段并且调用********");
        Field f1 = stuClass.getField("name");
        Field f2 = stuClass.getField("name02");
        // 这里展现已经获取到了两个 public 类型的 参数
        System.out.println("这是 name ：" + f1);
        System.out.println("这是 name02：" + f2);

        // 创建出一个 Student 对象 ==> new Student();
        Object obj1 = stuClass.getConstructor().newInstance();
        // 这里的 set 就是赋值操作即 ==> stu.name = "名称1"
        f1.set(obj1, "名称1");
        f2.set(obj1, "名称2");
        // 进行验证，这里的操作是将 obj 进行强制类型转换，转换为 Student 之后进行验证
        Student stu = (Student) obj1;
        System.out.println("验证姓名：" + stu.name);
        System.out.println("验证姓名：" + stu.name02);

        // 尝试获取私有字段并且调用
        System.out.println("********获取所有的字段(包括私有、受保护、默认)并且调用********");
        Field pf1 = stuClass.getDeclaredField("phoneNUM");
        Field pf2 = stuClass.getDeclaredField("age");

        System.out.println(pf1);
        System.out.println(pf2);
        // 暴力反射，解除私有设定
        pf1.setAccessible(true);
        pf2.setAccessible(true);

        Object obj2 = stuClass.getConstructor().newInstance();

        pf1.set(obj2, "1539999999999");
        pf2.set(obj2, 11);
        Student stu2 = (Student) obj2;
        System.out.println("获取到所有类型字段后的 toString 方法" + stu2.toString());
    }
}
